package com.leeoohoo.handlers;

import com.leeoohoo.base.BaseController;
import com.leeoohoo.base.BaseService;
import com.leeoohoo.base.Result;
import com.leeoohoo.common.UserContext;
import com.leeoohoo.common.UserHolder;
import com.leeoohoo.focus.FocusOn;
import com.leeoohoo.focus.FocusOnType;
import com.leeoohoo.focus.FocusService;
import com.leeoohoo.focus.dto.FocusOnDTO;
import com.leeoohoo.focus.dto.FocusOnUserDTO;
import com.oohoo.spacestationspringbootstarter.dto.query.EPage;
import com.oohoo.spacestationspringbootstarter.dto.query.EQ;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.Disposable;
import reactor.core.publisher.Mono;

import java.util.Objects;

@RestController
@RequestMapping("focus")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class FocusHandler extends BaseController<FocusOn, Long, FocusOnUserDTO, FocusOnDTO> {


    private final FocusService focusService;


    /**
     * 获取粉丝的用户列表
     *
     * @param focus
     * @return
     */
    @PostMapping("getFollowers")
    public Mono<Result<EPage<FocusOnUserDTO>>> getFollowers(@RequestBody Mono<FocusOnUserDTO> focus) {
        return super.page(focus.map(it -> {
            it.setType(FocusOnType.FOLLOW.getCode());
            return it;
        }));
    }


    /**
     * 获取关注列表
     *
     * @param focus
     * @return
     */
    @PostMapping("getFocusOn")
    public Mono<Result<EPage<FocusOnUserDTO>>> getFocusOn(@RequestBody Mono<FocusOnUserDTO> focus) {
        return super.page(focus.map(it -> {
            it.setType(FocusOnType.FOLLOWED.getCode());
            return it;
        }));
    }


    /**
     * 关注/取消关注
     *
     * @param focus
     * @return
     */
    @PostMapping("focusOnAndunFocusOn")
    @Transactional
    public Mono<Result<Void>> focusOn(@RequestBody @Validated Mono<FocusOnDTO> focus) {
        UserContext myUser = UserHolder.getMyUser();
        Disposable subscribe = focus.subscribe(it -> {
            UserHolder.setMyUser(myUser);
            FocusOn focusOn = ifFocusOnd(myUser, it.getOtherUserId());
            if (Objects.isNull(focusOn)) {
                it.setUserId(myUser.getId());
                it.setType(FocusOnType.FOLLOW.getCode());
                this.getService().save(it);
            }
            this.getService().logicDelete(focusOn.getId());
        });
        return Mono.just(Result.success());
    }


    private FocusOn ifFocusOnd(UserContext myUser, Long otherUserId) {
        FocusOn one = this.getService().getButler().findOne(EQ.find(FocusOn.class)
                        .select(FocusOn.class)
                        .where()
                        .eq(FocusOn::getUserId, myUser.getId())
                        .eq(FocusOn::getOtherUserId, otherUserId)
                        .eq(FocusOn::getType, FocusOnType.FOLLOW.getCode()),
                FocusOn.class);
        return one;
    }

    @Override
    public BaseService<FocusOn, Long> getService() {
        return focusService;
    }
}
